﻿
<!--***** NOTA BENE: THIS COMPILES BUT DOES NOT RUN ***** -->
<!--*****       FOR EXPLANTORY PURPOSES ONLY        ***** -->
<!--*****   THAT SAID, PLENTY OF GOOD STUFF BELOW   ***** -->

<UserControl
    x:Class="Markup.Programming.Samples.Syntax"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:p="http://markupprogramming.codeplex.com/markup/programming"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Height="300" Width="300">
    <Grid>
        <Grid.Resources>

            <!-- Resources so we can refer to them later. -->
            <SolidColorBrush Color="Blue" x:Key="BlueBrush"/>

            <!-- a module is a function library -->
            <p:Module x:Key="SyntaxFunctions">
                
                <!--
                
                Everything in the ValueSamples function produces a value.
                That is to say they are all expressions.  Mastering
                expressions is an basic skill as expressions are
                used in almost all statements.
                
                -->
                <p:Function FunctionName="ValueSamples">

                    <!-- sample values using ordinary XAML syntax -->
                    <p:Expr Value="An ordinary string"/>
                    <p:Expr>An ordinary string</p:Expr>
                    <p:Expr Value="{StaticResource BlueBrush}"/>
                    <p:Expr Value="{Binding ElementName=Button}"/>
                    <p:Expr Value="{Binding FirstName}"/>
                    
                    <!-- use parameter value indirection -->
                    <p:Get Path="$i"/>
                    <p:Path>$i</p:Path>

                    <!-- explicit type conversion -->
                    <p:Expr Value="42" TypePath="[Int32]"/>
                    
                    <!-- syntax without conversion -->
                    <p:Expr>
                        <sys:Int32>42</sys:Int32>
                    </p:Expr>
                    
                    <!-- supply types as values -->
                    <p:Path>[Int32]</p:Path>
                    <p:Expr Path="[Int32]"/>
                    <p:Expr Value="{x:Type sys:Int32}"/>
                    <p:Expr>
                        <x:Type TypeName="sys:Int32"/>
                    </p:Expr>

                    <!-- use get accessors -->
                    <p:Get Var="$i"/>
                    <p:Get Source="{StaticResource BlueBrush}"/>
                    <p:Get Context="{StaticResource BlueBrush}" PropertyName="Color"/>
                    <p:Get Path="$c" PropertyName="Count"/>
                    <p:Get Context="{Binding ElementName=Button}" DependencyProperty="Button.Command"/>
                    
                    <!-- use set accessors -->
                    <p:Set Var="$s" Value="New Value"/>
                    <p:Set Target="{Binding FirstName, Mode=TwoWay}" Value="Bill"/>
                    <p:Set Target="{Binding}" PropertyName="FirstName" Value="Bill"/>
                    <p:Set Var="$c" PropertyName="Count" Value="10"/>
                    <p:Set Op="Increment" Path="$c" PropertyName="Total"/>

                    <!-- use item accessor for arrays, collections and dictionaries -->
                    <p:GetItem Path="$x" Index="0"/>
                    <p:GetItem Path="$x" IndexPath="$i"/>
                    <p:GetItem Path="$array3D">
                        <p:Get Path="$i"/>
                        <p:Get Path="$j"/>
                        <p:Get Path="$k"/>
                    </p:GetItem>

                    <!-- all accessors can use context and context is inherited -->
                    <p:Expr Context="{StaticResource BlueBrush}">
                        <p:Get Path="Color"/>
                    </p:Expr>

                    <!-- use operators with optional conversions -->
                    <p:Operator Value1="abc" Op="Plus" Value2="def"/>
                    <p:Operator TypePath="[Int32]" Value1="2" Op="Times" Value2="2"/>
                    <p:Operator TypePath="[Boolean]" Op="Not" Value="True"/>
                    
                    <!-- use binary operator with one or two parameters -->
                    <p:Operator Path1="$i" Op="LessThan" Value2="10"/>
                    <p:Operator Path1="$i" Op="LessThan" Path2="$j"/>
                        
                    <!-- use operators in params mode -->
                    <p:Operator Op="Plus">
                        <p:Expr TypePath="[Int32]" Value="1"/>
                        <p:Expr TypePath="[Int32]" Value="2"/>
                        <p:Expr TypePath="[Int32]" Value="3"/>
                    </p:Operator>
                    
                    <!-- use short-circuit operators to avoid crashes -->
                    <p:Operator Op="AndAnd">
                        <p:Operator Op="NotIsNull" Path="$p"/>
                        <p:Get Path="$p" PropertyName="IsReady"/>
                    </p:Operator>

                    <!-- create a dynamic object -->
                    <p:Object>
                        <p:Property PropertyName="FirstName" Value="Bill"/>
                        <p:Property PropertyName="LastName" Value="Smith"/>
                    </p:Object>
                    
                    <!-- create a traditional object -->
                    <p:Object Path="[Button]">
                        <p:Property PropertyName="Content" Value="Click Me!"/>
                        <p:Property PropertyName="Opacity" Value="0.5"/>
                    </p:Object>

                    <!-- don't be seduced into thinking this is static -->
                    <!-- it is a brand new object with new computed values -->
                    <p:Object Path="[Button]">
                        <p:Property PropertyName="Content" Value="{Binding Firstname}"/>
                        <p:Property PropertyName="Opacity">
                            <p:Operator Op="Divide">
                                <p:Get Context="{Binding ElementName=Button}" PropertyName="Opacity"/>
                                <p:Expr Value="2"/>
                            </p:Operator>
                        </p:Property>
                    </p:Object>

                    <!-- create a smart generic observable collection -->
                    <p:Collection>
                        <p:Expr Value="abc"/>
                        <p:Expr Value="def"/>
                        <p:Expr Value="ghi"/>
                    </p:Collection>

                    <!-- filter collections using iterators -->
                    <p:Iterator>
                        <p:ForEach Var="$operator">
                            <p:ForEach.Value>
                                <p:Call Path="[Enum].GetValues([Op])"/>
                            </p:ForEach.Value>
                            <p:Yield Path="$operator">
                                <p:Yield.When>
                                    <p:Call Path="$operator.Contains('Bitwise')"/>
                                </p:Yield.When>
                            </p:Yield>
                        </p:ForEach>
                    </p:Iterator>
                    
                </p:Function>
            </p:Module>
        </Grid.Resources>

        <Button Content="Click Me">
            <p:Attached.Operations>
                <p:CallHandler EventName="Click => MessageBox].Show('Hello, world!')"/>
            </p:Attached.Operations>
        </Button>

        <Button Content="Click Me">
            <p:Attached.Operations>
                <p:EventHandler Path="Click">
                    <p:Call Path="[MessageBox].Show('Hello, world!')"/>
                </p:EventHandler>
            </p:Attached.Operations>
        </Button>
        
    </Grid>
</UserControl>
